package net.yambal.RTM.Method
{
	import flash.events.EventDispatcher;
	
	import net.yambal.RTM.Event.ListsEvent;
	import net.yambal.RTM.Event.RestErrorEvent;
	import net.yambal.RTM.Event.RestEvent;
	import net.yambal.RTM.Event.TimelineEvent;
	import net.yambal.RTM.Items.RTMList;
	import net.yambal.RTM.Items.RTMTransaction;
	import net.yambal.RTM.RestWrapper.RestService;
	import net.yambal.RTM.Utilty.Parser;
	import net.yambal.RTM.Utilty.RTMBooleanUtil;
	
	
	[Event(name="lists", type="net.yambal.RTM.Event.ListsEvent")]
	[Event(name="add", type="net.yambal.RTM.Event.ListsEvent")]
	[Event(name="archive", type="net.yambal.RTM.Event.ListsEvent")]
	[Event(name="set_default_list", type="net.yambal.RTM.Event.ListsEvent")]
	[Event(name="delete", type="net.yambal.RTM.Event.ListsEvent")]
	[Event(name="set_name", type="net.yambal.RTM.Event.ListsEvent")]
	[Event(name="un_archive", type="net.yambal.RTM.Event.ListsEvent")]
	public class Lists extends EventDispatcher
	{
		public function Lists()
		{
		}
		
		// --------------------------------------------------------------
		/**
		 * リスト一覧を得る
		 **/
		public function getLists(api_key:String, shared_secret:String, token:String):void{
			var s:RestService = new RestService(RestService.METHOD_LISTS_GET_LISTS, shared_secret);
			s.addParameta("api_key", api_key);
			s.addParameta("auth_token", token);
			s.addEventListener(RestEvent.RTM_RESULT, this.onGetLists);
			s.addEventListener(RestErrorEvent.RTM_FAULT, this.onFaultGetLists);
			s.send();
		}
		
		private function onFaultGetLists(e:RestErrorEvent):void{
			trace(e.code);
			trace(e.massage);
		}
		
		private function onGetLists(e:RestEvent):void{
			var s:RestService = e.currentTarget as RestService;
			s.removeEventListener(RestEvent.RTM_RESULT, this.onGetLists);
			s.removeEventListener(RestErrorEvent.RTM_FAULT, this.onFaultGetLists);

			var res:Array = Parser.ListXMLListToList(e.result_xml.descendants("list"));
			
			this.dispatchEvent(new ListsEvent(ListsEvent.LISTS, res));
		}
		
		// --------------------------------------------------------------
		/**
		 * Listを追加する
		 **/
		public function Add(api_key:String, shared_secret:String, token:String, name:String):void{
			var tl:Timelines = new Timelines();
			tl.addEventListener(TimelineEvent.CREATE, this.onCreateTimeline);
			
			// イベントにリレーする設定
			var ro:Object = new Object();
			ro.name = name;
			
			tl.create(api_key, shared_secret, token, ro);
		}
		
		private function onCreateTimeline(e:TimelineEvent):void{
			var tl:Timelines = e.currentTarget as Timelines;
			tl.removeEventListener(TimelineEvent.CREATE, this.onCreateTimeline);

			var s:RestService = new RestService(RestService.METHOD_LISTS_ADD, e.shared_secret, e.relay_obj);
			s.addParameta("api_key", e.api_key);
			s.addParameta("auth_token", e.token);
			s.addParameta("name", String(e.relay_obj.name));
			s.addParameta("timeline", String(e.timeline));
			
			s.addEventListener(RestEvent.RTM_RESULT, this.onAdd);
			s.addEventListener(RestErrorEvent.RTM_FAULT, this.onFaultAdd);
			s.send();
		}
		
		private function onFaultAdd(e:RestErrorEvent):void{
			trace(e.code);
			trace(e.massage);
		}
		
		private function onAdd(e:RestEvent):void{
			var s:RestService = e.currentTarget as RestService;
			s.removeEventListener(RestEvent.RTM_RESULT, this.onAdd);
			s.removeEventListener(RestErrorEvent.RTM_FAULT, this.onFaultAdd);

			var added:RTMList = Parser.ListXMLToList(e.result_xml.list[0]);
			
			var t:RTMTransaction = new RTMTransaction();
			t.id = e.result_xml.transaction.@id;
			t.undoable = RTMBooleanUtil.toBoolean(e.result_xml.transaction.@undoable);
			t.process = "リストの追加";
			
			this.dispatchEvent(new ListsEvent(ListsEvent.ADD, null, added, t));
		}
		
		// --------------------------------------------------------------
		/**
		 * Archive
		 **/
		public function Archive(api_key:String, shared_secret:String, token:String, list:RTMList):void{
			
			
			var tl:Timelines = new Timelines();
			tl.addEventListener(TimelineEvent.CREATE, this.onCreateTimelineForArchive);
			
			// イベントにリレーする設定
			var ro:Object = new Object();
			ro.list = list;
			
			tl.create(api_key, shared_secret, token, ro);
		}
		private function onCreateTimelineForArchive(e:TimelineEvent):void{
			var tl:Timelines = e.currentTarget as Timelines;
			tl.removeEventListener(TimelineEvent.CREATE, this.onCreateTimelineForArchive);
			
			var li:RTMList = e.relay_obj.list as RTMList;
			
			var s:RestService = new RestService(RestService.METHOD_LISTS_ARCHIVE, e.shared_secret, li);
			s.addParameta("api_key", e.api_key);
			s.addParameta("auth_token", e.token);
			s.addParameta("list_id", String(li.id));
			s.addParameta("timeline", String(e.timeline));
			
			s.addEventListener(RestEvent.RTM_RESULT, this.onArchive);
			s.addEventListener(RestErrorEvent.RTM_FAULT, this.onFaultArchive);
			s.send();
		}
		private function onFaultArchive(e:RestErrorEvent):void{
			trace(e.code);
			trace(e.massage);
		}
		private function onArchive(e:RestEvent):void{
			var s:RestService = e.currentTarget as RestService;
			s.removeEventListener(RestEvent.RTM_RESULT, this.onArchive);;
			s.removeEventListener(RestErrorEvent.RTM_FAULT, this.onFaultArchive);
			
			var archived:RTMList = Parser.ListXMLToList(e.result_xml.list[0]);
			
			var t:RTMTransaction = new RTMTransaction();
			t.id = e.result_xml.transaction.@id;
			t.undoable = RTMBooleanUtil.toBoolean(e.result_xml.transaction.@undoable);
			t.process = "リストを圧縮";
			
			this.dispatchEvent(new ListsEvent(ListsEvent.ARCHIVE, null, archived, t));
		}
		
		// --------------------------------------------------------------
		/**
		 * setDefaultList
		 **/
		public function setDefaultList(api_key:String, shared_secret:String, token:String, list:RTMList):void{
			var tl:Timelines = new Timelines();
			tl.addEventListener(TimelineEvent.CREATE, this.onCreateTimelineForSetDefaultList);
			
			// イベントにリレーする設定
			var ro:Object = new Object();
			ro.list = list;
			
			tl.create(api_key, shared_secret, token, ro);
		}
		private function onCreateTimelineForSetDefaultList(e:TimelineEvent):void{
			var tl:Timelines = e.currentTarget as Timelines;
			tl.removeEventListener(TimelineEvent.CREATE, this.onCreateTimelineForSetDefaultList);
			
			var li:RTMList = e.relay_obj.list as RTMList;
			
			var s:RestService = new RestService(RestService.METHOD_LISTS_SET_DEFAULT_LIST, e.shared_secret, li);
			s.addParameta("api_key", e.api_key);
			s.addParameta("auth_token", e.token);
			s.addParameta("list_id", String(li.id));
			s.addParameta("timeline", String(e.timeline));

			s.addEventListener(RestEvent.RTM_RESULT, this.onSetDefaultList);
			s.addEventListener(RestErrorEvent.RTM_FAULT, this.onFaultSetDefaultList);
			s.send();
		}
		private function onFaultSetDefaultList(e:RestErrorEvent):void{
			trace(e.code);
			trace(e.massage);
		}
		private function onSetDefaultList(e:RestEvent):void{
			var s:RestService = e.currentTarget as RestService;
			s.removeEventListener(RestEvent.RTM_RESULT, this.onSetDefaultList);
			s.removeEventListener(RestErrorEvent.RTM_FAULT, this.onFaultSetDefaultList);
			
			// resultでListは帰らないので補完
			var list:RTMList = e.relay_obj as RTMList;
			
			var t:RTMTransaction = new RTMTransaction();
			t.id = e.result_xml.transaction.@id;
			t.undoable = RTMBooleanUtil.toBoolean(e.result_xml.transaction.@undoable);
			t.process = "規定のリスト";
			
			this.dispatchEvent(new ListsEvent(ListsEvent.SET_DEFAULT_LIST, null, list, t));
		}
		
		// --------------------------------------------------------------
		/**
		 * delete
		 **/
		public function Delete(api_key:String, shared_secret:String, token:String, list:RTMList):void{
			var tl:Timelines = new Timelines();
			tl.addEventListener(TimelineEvent.CREATE, this.onCreateTimelineForDelete);
			
			// イベントにリレーする設定
			var ro:Object = new Object();
			ro.list = list;
			
			tl.create(api_key, shared_secret, token, ro);
		}
		private function onCreateTimelineForDelete(e:TimelineEvent):void{
			var tl:Timelines = e.currentTarget as Timelines;
			tl.removeEventListener(TimelineEvent.CREATE, this.onCreateTimelineForDelete);
			
			var li:RTMList = e.relay_obj.list as RTMList;
			
			var s:RestService = new RestService(RestService.METHOD_LISTS_DELETE, e.shared_secret, li);
			s.addParameta("api_key", e.api_key);
			s.addParameta("auth_token", e.token);
			s.addParameta("list_id", String(li.id));
			s.addParameta("timeline", String(e.timeline));
			
			s.addEventListener(RestEvent.RTM_RESULT, this.onDelete);
			s.addEventListener(RestErrorEvent.RTM_FAULT, this.onFaultDelete);
			s.send();
		}
		
		private function onFaultDelete(e:RestErrorEvent):void{
			trace(e.code);
			trace(e.massage);
		}
		private function onDelete(e:RestEvent):void{
			var s:RestService = e.currentTarget as RestService;
			s.removeEventListener(RestEvent.RTM_RESULT, this.onDelete);;
			s.removeEventListener(RestErrorEvent.RTM_FAULT, this.onFaultDelete);
			
			var deleted:RTMList = Parser.ListXMLToList(e.result_xml.list[0]);
			
			var t:RTMTransaction = new RTMTransaction();
			t.id = e.result_xml.transaction.@id;
			t.undoable = RTMBooleanUtil.toBoolean(e.result_xml.transaction.@undoable);
			t.process = "リストの削除";
			
			this.dispatchEvent(new ListsEvent(ListsEvent.DELETE, null, deleted, t));
			
		}
		
		// --------------------------------------------------------------
		/**
		 * 名前を変更する
		 **/
		public function setName(api_key:String, shared_secret:String, token:String, list:RTMList):void{
			var tl:Timelines = new Timelines();
			tl.addEventListener(TimelineEvent.CREATE, this.onCreateTimelineForSetName);
			
			// イベントにリレーする設定
			var ro:Object = new Object();
			ro.list = list;
			
			tl.create(api_key, shared_secret, token, ro);
		}
		
		private function onCreateTimelineForSetName(e:TimelineEvent):void{
			var tl:Timelines = e.currentTarget as Timelines;
			tl.removeEventListener(TimelineEvent.CREATE, this.onCreateTimelineForSetName);
			
			var li:RTMList = e.relay_obj.list as RTMList;
			
			var s:RestService = new RestService(RestService.METHOD_LISTS_SET_NAME, e.shared_secret, li);
			s.addParameta("api_key", e.api_key);
			s.addParameta("auth_token", e.token);
			s.addParameta("list_id", String(li.id));
			s.addParameta("name", String(li.name));
			s.addParameta("timeline", String(e.timeline));
			
			s.addEventListener(RestEvent.RTM_RESULT, this.onSetName);
			s.addEventListener(RestErrorEvent.RTM_FAULT, this.onFaultSetName);
			s.send();
		}
		private function onFaultSetName(e:RestErrorEvent):void{
			trace(e.code);
			trace(e.massage);
		}
		private function onSetName(e:RestEvent):void{
			var s:RestService = e.currentTarget as RestService;
			s.removeEventListener(RestEvent.RTM_RESULT, this.onSetName);
			s.removeEventListener(RestErrorEvent.RTM_FAULT, this.onFaultSetName);
			
			var named:RTMList = Parser.ListXMLToList(e.result_xml.list[0]);
			
			var t:RTMTransaction = new RTMTransaction();
			t.id = e.result_xml.transaction.@id;
			t.undoable = RTMBooleanUtil.toBoolean(e.result_xml.transaction.@undoable);
			t.process = "リスト名称の変更";
			
			this.dispatchEvent(new ListsEvent(ListsEvent.SET_NAME, null, named, t));
		}
		
		// --------------------------------------------------------------
		/**
		 * unArchive
		 **/
		public function unArchive(api_key:String, shared_secret:String, token:String, list:RTMList):void{
			var tl:Timelines = new Timelines();
			tl.addEventListener(TimelineEvent.CREATE, this.onCreateTimelineForUnArchive);
			
			// イベントにリレーする設定
			var ro:Object = new Object();
			ro.list = list;
			
			tl.create(api_key, shared_secret, token, ro);
		}
		
		private function onCreateTimelineForUnArchive(e:TimelineEvent):void{
			var tl:Timelines = e.currentTarget as Timelines;
			tl.removeEventListener(TimelineEvent.CREATE, this.onCreateTimelineForSetName);
			
			var li:RTMList = e.relay_obj.list as RTMList;
			
			var s:RestService = new RestService(RestService.METHOD_LISTS_UN_ARCHIVE, e.shared_secret, li);
			s.addParameta("api_key", e.api_key);
			s.addParameta("auth_token", e.token);
			s.addParameta("list_id", String(li.id));
			s.addParameta("timeline", String(e.timeline));
			
			s.addEventListener(RestEvent.RTM_RESULT, this.onUnArchive);
			s.addEventListener(RestErrorEvent.RTM_FAULT, this.onFaultUnArchive);
			s.send();
		}
		private function onFaultUnArchive(e:RestErrorEvent):void{
			trace(e.code);
			trace(e.massage);
		}
		
		private function onUnArchive(e:RestEvent):void{
			var s:RestService = e.currentTarget as RestService;
			s.removeEventListener(RestEvent.RTM_RESULT, this.onUnArchive);
			s.removeEventListener(RestErrorEvent.RTM_FAULT, this.onFaultUnArchive);
			
			var unArchived:RTMList = Parser.ListXMLToList(e.result_xml.list[0]);
			
			var t:RTMTransaction = new RTMTransaction();
			t.id = e.result_xml.transaction.@id;
			t.undoable = RTMBooleanUtil.toBoolean(e.result_xml.transaction.@undoable);
			t.process = "解凍";
						
			this.dispatchEvent(new ListsEvent(ListsEvent.UN_ARCHIVE, null, unArchived, t));
		}
		
		
		// -----------------------------------------------------------------------------
	}
}